/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.interpreter.backends.jena;

import java.util.Map;

/**
 *
 * @author Laurent WOUTERS
 */
public class JenaRuleDynHead extends JenaCustomBuiltin {
    private com.hp.hpl.jena.graph.Node sSubject;
    private com.hp.hpl.jena.graph.Node sProperty;
    private com.hp.hpl.jena.graph.Node sObject;
    private xowl.lang.owl2.Expression dSubject;
    private xowl.lang.owl2.Expression dProperty;
    private xowl.lang.owl2.Expression dObject;
    
    public void setSubject(com.hp.hpl.jena.graph.Node node) { sSubject = node; }
    public void setProperty(com.hp.hpl.jena.graph.Node node) { sProperty = node; }
    public void setObject(com.hp.hpl.jena.graph.Node node) { sObject = node; }
    public void setSubject(xowl.lang.owl2.Expression exp) { dSubject = exp; }
    public void setProperty(xowl.lang.owl2.Expression exp) { dProperty = exp; }
    public void setObject(xowl.lang.owl2.Expression exp) { dObject = exp; }
    
    public JenaRuleDynHead(JenaRepository repo, Map<xowl.interpreter.backends.rdf.XOWLVariableNode, com.hp.hpl.jena.graph.Node> vars) {
        super(repo, vars);
    }
    
    @Override public boolean bodyCall(com.hp.hpl.jena.graph.Node[] nodes, int length, com.hp.hpl.jena.reasoner.rulesys.RuleContext rc) { return false; }
    @Override public void headAction(com.hp.hpl.jena.graph.Node[] nodes, int length, com.hp.hpl.jena.reasoner.rulesys.RuleContext rc) {
        JenaQueryVariableEvaluator eval = getQueryEvaluator(rc);
        try {
            xowl.interpreter.impl.AggregatedEvaluator evaluator = getEvaluator();
            evaluator.addPart(eval);
            if (sSubject == null)
                sSubject = translate(evaluator, dSubject);
            else if (sSubject.isVariable())
                sSubject = rc.getEnv().getGroundVersion(sSubject);
            if (sProperty == null)
                sProperty = translate(evaluator, dProperty);
            else if (sProperty.isVariable())
                sProperty = rc.getEnv().getGroundVersion(sProperty);
            if (sObject == null)
                sObject = translate(evaluator, dObject);
            else if (sObject.isVariable())
                sObject = rc.getEnv().getGroundVersion(sObject);
            com.hp.hpl.jena.graph.Triple triple = new com.hp.hpl.jena.graph.Triple(sSubject, sProperty, sObject);
            rc.add(triple);
            evaluator.removePart(eval);
        } catch (xowl.interpreter.XOWLException ex) { repository.getLog().error(JenaRepository.name, ex.getHeadline(), ex); }
    }
    
    private com.hp.hpl.jena.graph.Node translate(xowl.interpreter.impl.AggregatedEvaluator evaluator, xowl.lang.owl2.Expression exp) throws xowl.interpreter.XOWLException {
        xowl.lang.runtime.Value value = evaluator.evaluate(evaluator, exp);
        xowl.interpreter.backends.rdf.RDFNode node = repository.getRDFNode(value);
        return repository.getJenaNode(node);
    }
}
